#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"

static const int RX_BUF_SIZE = 1024;
#define TXD_PIN 4
#define RXD_PIN 5

int sendData(const char* logName, const char* data)
{
    const int len = strlen(data);
    const int txBytes = uart_write_bytes(UART_NUM_0, data, len);
    ESP_LOGI(logName, "Wrote %d bytes", txBytes);
    return txBytes;
}

void uart_init(void)
{
    const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    
    uart_driver_install(UART_NUM_0, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_param_config(UART_NUM_0, &uart_config);
    uart_set_pin(UART_NUM_0, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

char rx_data[256] = {0};
uint8_t rx_data_len = 0;

void app_main(void)
{
    uart_init();
    
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    sendData("UART", "This is a uart demo\n");

    while(1)
    {
        rx_data_len = uart_read_bytes(UART_NUM_0, rx_data, 256, 100 / portTICK_PERIOD_MS);
        if(rx_data_len > 0)
        {
            rx_data[rx_data_len] = 0;
            ESP_LOGI("UART", "Read %d bytes: '%s'", rx_data_len, rx_data);
            sendData("UART", rx_data);
        }
    }
}
